import axios from 'axios';
import { throttle } from 'lodash-es';
import { CacheManager } from './cache';
import { RequestQueue } from './queue';
import { HttpError } from './error';
import { ParamsFilter } from './filter';

export class HttpClient {
  #axios;
  #cache;
  #queue;
  #pendingRequests = new Map();

  constructor(baseURL, ...config) {
    this.#axios = axios.create({
      baseURL,
      timeout: 10000,
      headers: {
        'Content-Type': 'application/json'
      },
      ...config,
    });

    this.#cache = new CacheManager();
    this.#queue = new RequestQueue();

    this.#setupInterceptors();
  }

  #setupInterceptors() {
    this.#axios.interceptors.request.use(
      config => {
        // 注入token
        const token = localStorage.getItem('token');
        if (token) {
          config.headers.Authorization = `Bearer ${token}`;
        }

        // 处理重复请求
        this.#removePendingRequest(config);
        this.#addPendingRequest(config);

        return config;
      },
      error => Promise.reject(error)
    );

    this.#axios.interceptors.response.use(
      response => {
        this.#removePendingRequest(response.config);
        return response.data;
      },
      error => {
        if (axios.isCancel(error)) {
          return Promise.reject(new Error('Request cancelled'));
        }
        return Promise.reject(HttpError.from(error));
      }
    );
  }

  #addPendingRequest = (config) => {
    const key = this.#getRequestKey(config);
    const source = axios.CancelToken.source();
    config.cancelToken = source.token;
    this.#pendingRequests.set(key, source);
  };

  #removePendingRequest = (config) => {
    const key = this.#getRequestKey(config);
    if (this.#pendingRequests.has(key)) {
      const source = this.#pendingRequests.get(key);
      source.cancel();
      this.#pendingRequests.delete(key);
    }
  };

  #getRequestKey = (config) => {
    return `${config.method}_${config.url}_${JSON.stringify(config.params)}_${JSON.stringify(config.data)}`;
  };

  async request(config) {
    // 应用参数过滤
    const filteredConfig = this.#filterRequestParams(config);
    // 处理缓存
    if (filteredConfig.cache?.enable) {
      const cachedData = this.#cache.get(
        filteredConfig.url,
        filteredConfig.cache,
        filteredConfig.params
      );
      if (cachedData) {
        return cachedData;
      }
    }

    // 处理队列
    if (filteredConfig.queue?.enable) {
      return this.#queue.add(
        () => this.#axios.request(filteredConfig),
        filteredConfig.queue
      );
    }

    const response = await this.#axios.request(filteredConfig);

    // 设置缓存
    if (filteredConfig.cache?.enable) {
      this.#cache.set(filteredConfig.url, response, filteredConfig.cache, filteredConfig.params);
    }

    return response;
  }

  // 节流的 GET 请求
  get = throttle((
      url,
      config
    ) => this.request({ ...config, method: 'GET', url }),
    1000
  );

  post(
    url,
    data,
    config
  ) {
    return this.request({ ...config, method: 'POST', url, data });
  }

  put(
    url,
    data,
    config
  ) {
    return this.request({ ...config, method: 'PUT', url, data });
  }

  delete(
    url,
    config
  ) {
    return this.request({ ...config, method: 'DELETE', url });
  }

  #filterRequestParams(config) {
    const filterConfig = {
      enable: true,  // 默认启用过滤
      rules: {
        removeEmpty: true,
        removeNull: true,
        removeUndefined: true,
        removeFalsy: false
      },
      ...config.filter
    };

    if (!filterConfig.enable) {
      return config;
    }

    return {
      ...config,
      params: ParamsFilter.filter(config.params, filterConfig),
      data: ParamsFilter.filter(config.data, filterConfig)
    };
  }
}